/* eslint-disable no-unused-vars */
/* eslint-disable react/destructuring-assignment */
/* eslint-disable class-methods-use-this */
/* eslint-disable react/no-access-state-in-setstate  */
/* eslint-disable react/sort-comp  */
/* eslint-disable no-param-reassign  */
/* eslint-disable react/no-find-dom-node  */
/* eslint-disable import/no-cycle */
import { Form, Tabs, Input, Slider, InputNumber, Select, Button, Badge, Checkbox } from 'antd';
import React from 'react';
import ReactDOM from 'react-dom';
import ControlErrorBoundary from '../common/ControlErrorBoundary';
import DesignUtil from '../common/DesignUtil';
import ToolBarDrap from '../common/ToolBarDrap';

const { TabPane } = Tabs;

/**
 * 控件基础模板
 * 定义控件基础协议，所有控件都继承此模板，并重载实现
 */
class BaseControl {
  constructor(props, dataProps, extProps) {
    const dataProps2 = dataProps || {};
    this.data = {
      key: props.designkey || `at${DesignUtil.UUID(16)}`, // 控件唯一标识,用于控件查找和绑定，唯一
      title: props.label || '控件', // 控件标题，显示在form界面上使用
      showTitle: true, // 隐藏/显示标题
      type: 'Base', // 控件类型
      order: 0, // 界面的排序位置
      widthPercent: 100, // 宽度百分比
      height: 0, // 高度px，0为auto
      justify: 'flex-start', // flex 排列循序
      align: 'flex-start',
      authoritys: [], // 访问权限{roleid:"",access:"read"}
      custom: false, // 是否是自定义控件
      authority: 'write', // 当前用户最终换算出来的呈现权限,枚举:read?hide?write? 需要后端换算
      draggable: true, // 是否可拖动
      canEdit: true, // 是否可编辑
      tag: '', // 存储隐藏信息
      ...dataProps2,
    };
    this.props = props;
    this.value = null; // 当前用户最终value,不同控件格式不一样,比如子表单可能为json
    // this.init();
    this.name = '控件'; // 控件名称，显示工具栏上
    // 控件显示icon图标
    this.icon = 'http://www.icosky.com/icon/ico/Internet%20%26%20Web/Xiao/Xiao%201.ico';
    this.extProps = extProps; // 控件扩展属性
    this.domNode = null; // 控件主dom元素ref
  }

  init(parentForm) {
    // 调用am接口
    // this.setState({
    //   roles: [
    //     { id: 1, name: '角色1' },
    //     { id: 2, name: '角色2' },
    //   ],
    // });
  }

  // 页面加载完成(仅一次发生)
  pageloaded(parentForm) {}

  // 加载json
  load(json) {
    this.data = { ...this.data, ...json };
  }

  // 获取后端协议json，后台解析使用
  getPropertyJson() {
    return { ...this.data };
  }

  // 获取前端设计模型json标准
  getDesignModelJson() {
    return this.getPropertyJson();
  }

  // 获取formItem控件的value值
  getJsonValue(jsonValues) {
    jsonValues.push({ key: this.data.key, title: this.data.title, value: this.value, type: this.data.type });
  }

  // 设置formItem控件的value值
  setJsonValue(jsonValues) {
    const find = jsonValues.find((c) => c.key === this.data.key);
    if (find != null) {
      this.value = find.value;
    }
  }

  // 获取设计属性控件(最终渲染的控件)，用于控件定义最终渲染效果
  getDesignControl(parentForm) {
    return <React.Fragment {...this.extProps} />;
  }

  // 获取渲染的大小位置
  getClientRect() {
    if (this.domNode == null) return null;
    const node = ReactDOM.findDOMNode(this.domNode);
    return node.getBoundingClientRect();
  }

  // 初始化属性设计
  initProperty(parentForm) {}

  // 验证校验
  validate(rule, v, callback) {
    const value2 = v || this.value;
    // if (value2 == null) {
    //   value2 = this.data?.defaultValue;
    // }
    if (this.data.required === true && (value2 === '' || value2 == null)) {
      return Promise.reject('请输入内容');
    } else {
      return Promise.resolve();
    }
  }

  // 权限
  authorityStyle(authority) {
    if (authority === 'read') {
      return { pointerEvents: 'none' };
    }
    if (authority === 'write') {
      return {};
    }
    if (authority === 'hide') {
      return { visibility: 'hidden' };
    }
    return {};
  }

  // 刷新绑定值
  refreashBind(parentForm) {
    Object.keys(this.data).forEach((key) => {
      if (key.toString().endsWith('Bind')) {
        const dataSourceKey = this.data[key];
        if (dataSourceKey !== '' && dataSourceKey != null) {
          const fromKey = key.replace('Bind', '');
          this.data[fromKey] = parentForm.dataSourceResults.get(dataSourceKey);
        }
      }
    });
  }

  // 获取属性设计的tab页面
  getPropertyTabs(parentForm) {
    return [
      <TabPane tab="基本配置" key="1">
        <Form.Item label="标题">
          <Input
            placeholder="输入标题"
            value={this.data.title}
            onChange={(event) => {
              this.data.title = event.target.value;
              parentForm.refreash();
            }}
          />
        </Form.Item>
        <Form.Item label="显示标题">
          <Checkbox
            checked={this.data.showTitle}
            onChange={(event) => {
              this.data.showTitle = event.target.checked;
              parentForm.refreash();
            }}
          />
        </Form.Item>

        <Form.Item label="宽度">
          <Slider
            value={this.data.widthPercent}
            onChange={(event) => {
              this.data.widthPercent = event;
              parentForm.refreash();
            }}
          />
        </Form.Item>
        <Form.Item label="高度">
          <InputNumber
            min={0}
            value={this.data.height}
            onChange={(event) => {
              this.data.height = event;
              parentForm.refreash();
            }}
          />
        </Form.Item>
        <Form.Item label="左右对齐">
          <Select
            onChange={(event) => {
              this.data.justify = event;
              parentForm.refreash();
            }}
            value={this.data.justify}
          >
            <Select.Option value="flex-start">左对齐</Select.Option>
            <Select.Option value="center">居中</Select.Option>
            <Select.Option value="flex-end">右对齐</Select.Option>
          </Select>
        </Form.Item>
        <Form.Item label="上下对齐">
          <Select
            value={this.data.align}
            onChange={(event) => {
              this.data.align = event;
              parentForm.refreash();
            }}
          >
            <Select.Option value="flex-start">上对齐</Select.Option>
            <Select.Option value="center">居中</Select.Option>
            <Select.Option value="flex-end">下对齐</Select.Option>
          </Select>
        </Form.Item>
        <Form.Item label="系统信息">
          <span>唯一key:</span>
          <Input disabled value={this.data.key} />
          <span>来源:</span>
          <Input disabled value={this.data.custom ? '用户自定义' : '系统自带'} />
          <span>顺序:</span>
          <Input disabled value={this.data.order} />
          <span>类型:</span>
          <Input disabled value={this.name} />
        </Form.Item>
      </TabPane>,
      <TabPane tab="权限配置" key="2">
        <Form.Item label="通用权限">
          <Select
            value={this.data.authority}
            onChange={(event) => {
              this.data.authority = event;
              parentForm.refreash();
            }}
          >
            <Select.Option value="read">只读</Select.Option>
            <Select.Option value="write">读写</Select.Option>
            <Select.Option value="hide">隐藏</Select.Option>
          </Select>
        </Form.Item>
        <Form.Item label="用户权限">
          <Button
            type="link"
            onClick={() => {
              this.data.authoritys = [...this.data.authoritys, { roleid: -1, access: 'read' }];
              parentForm.refreash();
            }}
          >
            添加权限
          </Button>
          {this.data.authoritys.map((item) => {
            return (
              <>
                <Select value={{ value: item.roleid }}>
                  {this.roles?.map((role) => {
                    return <Select.Option value={role.id}>{role.name}</Select.Option>;
                  })}
                </Select>
                <Select value={{ value: item.access }}>
                  <Select.Option value="read">只读</Select.Option>
                  <Select.Option value="write">读写</Select.Option>
                  <Select.Option value="hide">隐藏</Select.Option>
                </Select>
                <span>编辑,删除</span>
              </>
            );
          })}
        </Form.Item>
      </TabPane>,
    ];
  }

  // 当前控件的渲染效果
  render(parentForm) {
    this.refreashBind(parentForm);
    const item = <>{this.getDesignControl(parentForm)}</>;
    if (parentForm?.isEditState && this.data.canEdit) {
      return (
        <div
          ref={(ref) => {
            this.domNode = ref;
          }}
          key={this.data.key}
          style={{
            width: `${this.data.widthPercent}%`,
            height: this.data.height === 0 ? 'auto' : `${this.data.height}px`,
            border: this.data.draggable ? '1px dashed red' : '1px dashed gray',
          }}
          onClick={(e) => {
            parentForm.clickControlEditProperty(e, this);
            e.stopPropagation();
          }}
          {...new ToolBarDrap.DragData(parentForm.tooldrap, {
            key: this.data.key,
            type: this.data.type,
          }).bindDrapStartEventProps(this.data.draggable)}
          onContextMenu={(e) => {
            parentForm.showControlMenu(e, { props: { key: this.data.key } });
          }}
          order={this.data.order}
        >
          <Form.Item
            name={this.data.key}
            rules={[{ validator: async (rule, v, callback) => this.validate(rule, v, callback) }]}
            {...this.props}
            label={this.data.showTitle ? this.data.title : ''}
            style={{ ...this.props?.style, ...this.authorityStyle(this.data.authority) }}
          >
            <ControlErrorBoundary>{item}</ControlErrorBoundary>
          </Form.Item>
        </div>
      );
    } else {
      return (
        <div
          style={{
            width: `${this.data.widthPercent}%`,
            height: this.data.height === 0 ? 'auto' : `${this.data.height}px`,
          }}
          key={this.data.key}
        >
          <Form.Item
            name={this.data.key}
            rules={[{ validator: async (rule, v, callback) => this.validate(rule, v, callback) }]}
            {...this.props}
            label={this.data.showTitle ? this.data.title : ''}
            style={{ ...this.props?.style, ...this.authorityStyle(this.data.authority) }}
          >
            <ControlErrorBoundary>{item}</ControlErrorBoundary>
          </Form.Item>
        </div>
      );
    }
  }
}

export default BaseControl;
